<?php
namespace api\modules\v1\controllers;
use api\common\models\Mar;
use api\common\models\User;
use api\func\func;
use api\modules\v1\models\Balancewater;
use api\modules\v1\models\Msg;
use api\modules\v1\models\News;
use api\modules\v1\models\Reward;
use Yii;
use api\cs\alipay\AopClient;
use api\cs\weixin\wechatAppPay;
use api\common\controllers\UserController as U;
use yii\base\Exception;
use yii\helpers\Url;

class PayController extends U
{
    public $modelClass = '';
    protected $_alipay_obj;//支付宝对象
    protected $_weixin_obj;//微信对象

    public function beforeAction($action)
    {
        $this->enableCsrfValidation = false;//csrf关闭
        return parent::beforeAction($action);
    }

    public function actions()
    {
        $actions = parent::actions();
        unset($actions['index'],$actions['update'], $actions['create'], $actions['delete'], $actions['view']); //卸载操作
        return $actions;
    }

    public function behaviors() {
        if(in_array(Yii::$app->controller->action->id,['alipaynotify','wxnotify'])){
            $this->_is_auth = false;
            $this->_is_sign = false;
        }
        return parent::behaviors();
    }

    //支付宝基础数据实例化
    protected function alipayBase(){
        $this->_alipay_obj = new AopClient();
        $this->_alipay_obj->gatewayUrl = Yii::$app->params['gatewayUrl'];
        $this->_alipay_obj->appId = Yii::$app->params['appId'];
        $this->_alipay_obj->rsaPrivateKey = Yii::$app->params['rsaPrivateKey'];
        $this->_alipay_obj->format = "json";
        $this->_alipay_obj->charset= "UTF-8";
        $this->_alipay_obj->alipayrsaPublicKey = Yii::$app->params['alipayrsaPublicKey'];
    }

    //组织调用SDK数据
    protected function alipaySdk($data){
        $this->alipayBase();
        $sdkData  = [];
        $sdkData['app_id'] = $this->_alipay_obj->appId;
        $sdkData['charset'] = 'utf-8';
        $sdkData['format'] = $this->_alipay_obj->format;
        $sdkData['method'] = 'alipay.trade.app.pay';
        $sdkData['notify_url'] = Yii::$app->params['notify_url'];
        $sdkData['sign_type'] = 'RSA';
        $sdkData['timestamp'] = date('Y-m-d H:i:s');
        $sdkData['version'] = '1.0';
        $biz_content = [];
        $biz_content['subject'] = '用户打赏';
        $biz_content['body'] = '用户打赏';
        //$biz_content['seller_id'] = $data['reward_id'];
        $biz_content['out_trade_no'] = $data['order_num'];
        $biz_content['total_amount'] = $data['money'];
        $biz_content['product_code'] = 'QUICK_MSECURITY_PAY';
        $sdkData['biz_content'] = json_encode($biz_content,JSON_UNESCAPED_UNICODE);
        $sign = $this->_alipay_obj->rsaSign($sdkData); //签名数据
        $sdkData['sign'] = $sign;
        $sdk = http_build_query($sdkData);
        return $sdk;
    }

    /*
     * 回调通知
     */
    public function actionAlipaynotify(){
        $this->alipayBase();
        $post = Yii::$app->request->post();
       // if (false) { //签名数据
        if (!$this->_alipay_obj->rsaCheckV1($post,$this->_alipay_obj->alipayrsaPublicKey)) { //签名数据
            $this->logs(var_export($post,1),2);
            echo "checkSign failure";
            exit;
        }else{
            $this->logs(var_export($post,1),1);
            if($post['trade_status'] == 'TRADE_SUCCESS' || $post['trade_status'] == 'TRADE_FINISHED'){ //只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED
                if($reware = Reward::findOne(['order_num'=>$post['out_trade_no']])){ //1.验证out_trade_no
                    if($reware['money'] == $post['total_amount']){ //2.验证total_amount
                        if($this->_alipay_obj->appId == $post['app_id']){ //4.验证 app_id
                            if($reware['status'] != 1){
                                $rereward_user = User::findOne(['id'=>$reware['rereward_id']]);
                                $user_balance = $rereward_user['balance'];//获取的用户余额
                                $end_balance = $user_balance + $reware['money'];//计算结算后的余额
                                if(!User::updateAll(['balance'=>$end_balance],['id'=>$reware['rereward_id']])){ //更新余额
                                    $this->logs('用户余额修改失败: '.$end_balance.'--'.$reware['rereward_id'],2);
                                }

                                if(!Reward::updateAll(['status'=>1],['order_num'=>$reware['order_num']])){ //修改打赏表状态
                                    $this->logs('Reward表修改状态失败: '.$reware['order_num'],2);
                                }
                                //查询打赏人信息
                                $reward_user = User::findOne(['id'=>$reware['reward_id']]);
                                $reware_name = $reward_user['nickname'] != '' ? $reward_user['nickname'] : func::replace_phone($reward_user['phone']);

                                //查询文章信息
                                $news = $this->getContent($reware['catid'],$reware['news_id']);

                                //被打赏人 金额流水记录增加
                                $Balancewater = new Balancewater();
                                $msg = $reware_name.'打赏了您的文章《'.$news->title.'》'.$reware['money'].'元';
                                if(!$Balancewater->add($reware['rereward_id'],$reware['reward_id'],2,3,$reware['order_num'],1,$reware['money'],$end_balance,$msg,json_encode($post))){ //金额流水记录增加
                                    $this->logs('被打赏人user_balance_water表增加流水失败: '.json_encode($Balancewater->getFirstErrors()),2);
                                }

                                //打赏人 金额流水记录
                                $Balancewater = new Balancewater();
                                $msg = '您打赏了文章《'.$news->title.'》'.$reware['money'].'元';
                                if(!$Balancewater->add($reware['reward_id'],$reware['rereward_id'],1,1,$reware['order_num'],2,$reware['money'],$reward_user['balance'],$msg,json_encode($post))){ //金额流水记录增加
                                    $this->logs('打赏人user_balance_water表减少流水失败: '.json_encode($Balancewater->getFirstErrors()),2);
                                }

                                //发送消息
                                $msg = new Msg();
                                $msg->take_uid = $reware['rereward_id'];
                                $msg->send_uid = 0;
                                $msg->message = $reware_name.'打赏了您的文章《'.$news->title.'》'.$reware['money'].'元';
                                $msg->type = 99;
                                $msg->url = '';
                                $msg->time = date('Y-m-d H:i:s');
                                $msg->isread = 0;
                                $msg->isNewRecord = true;
                                $msg->save();

                                $this->logs('apilay_notify 验证通过',1);


                                //统计系统推送
                                try{
                                    $news_data = News::getInfoSim($reware['news_id'],$reware['catid']);
                                    if($news_data['thirdid'] !='' || $news_data['thirdid'] != 0){
                                        $user = func::IdToUser($news_data['thirdid']);
                                        $nickname = $user->nickname != '' ? $user->nickname :func::replace_phone($user->phone);
                                        $phone = $user->phone;
                                        $data = '{"User_id":'.$reware['rereward_id'].',"Article_id":'.$reware['news_id'].',"Article_type":'.$reware['catid'].',"Reward_channel":1,"Reward_money":'.$reware['money'].',"Reward_time":"'.date('Y-m-d H:i:s').'","Article_title":"'.$news_data['title'].'","Nickname":""'.$nickname.'","Phone":'.$phone.'}';
                                        $data = array('data' => $data,'key'=>'c3RhdGlzdGlj');
                                        $json = func::GoCurl('/api/reward/insert',  'POST',$data, $error_msg);
                                        $array = json_decode($json, true);
                                        if($array['Code'] != 10000){

                                        }
                                    }
                                }catch (Exception $e){}
                                //统计系统推送

                                echo 'success';
                                exit;
                            }
                        }else{
                            $this->logs('4.验证 app_id错误:'.$this->_alipay_obj->appId.'<-->'.$post['app_id'],2);exit();
                        }
                    }else{
                        $this->logs('2.验证 total_amount错误:'.$reware['money'].'<-->'.$post['total_amount'],2);exit();
                    }
                }else{
                    $this->logs('1.验证 out_trade_no错误:'.$post['out_trade_no'],2);exit();
                }
            }else{
                $this->logs('4.trade_status状态失败:'.$post['trade_status'],2);exit();
            }
        }
    }


    //微信基础数据实例化
    protected function wxBase(){
        $options = array(
            'appid' 	=> 	Yii::$app->params['wx_appid'],		//填写微信分配的公众开放账号ID
            'mch_id'	=>	Yii::$app->params['wx_mch_id'],				//填写微信支付分配的商户号
            'notify_url'=>	Yii::$app->params['wx_notify_url'],	//填写微信支付结果回调地址
            'key'		=>	Yii::$app->params['wx_key']				//填写  商户支付密钥Key。审核通过后，在微信发送的邮件中查看
        );
        $this->_weixin_obj = new wechatAppPay($options);
    }


    /*
     * 微信SDK数据
     * @param $data
     * @return mixed
     */
    protected function weixinSdk($data){
        $this->wxBase();
        $params['body'] = '用户打赏';						//商品描述
        $params['out_trade_no'] = $data['order_num'];	//自定义的订单号
        $params['total_fee'] = $data['money']*100;					//订单金额 只能为整数 单位为分
        $params['trade_type'] = 'APP';					//交易类型 JSAPI | NATIVE | APP | WAP
        $result = $this->_weixin_obj->unifiedOrder( $params );
        if($result['return_code'] == 'FAIL'){
            $this->logs('微信下单失败:'.$result['return_msg'],2,'wx');exit();
        }
        $sdk = $this->_weixin_obj->getAppPayParams( $result['prepay_id'] );
        return $sdk;
    }

    /*
     * 微信回调通知
     */
    public function actionWxnotify(){
        $this->wxBase();
        $post = file_get_contents('php://input');
        $this->logs('接收的数据:'.var_export($post,1),1,'wx');
        if (!$data = $this->_weixin_obj->getNotifyData()) { //是否成功通知
            $this->logs('XML数据解析失败',2,'wx');
            echo "checkSign failure";
            exit;
        }else{
            $sign = $data['sign'];
            unset($data['sign']);
            $verify_sign = $this->_weixin_obj->MakeSign($data);//生成验签签名
            if($sign != $verify_sign){
                $this->logs('sign签名验证错误:'.var_export($data,1),2,'wx');exit();
            }

            if($reware = Reward::findOne(['order_num'=>$data['out_trade_no']])){ //1.验证out_trade_no
                if($reware['money']*100 == $data['total_fee']){ //2.验证total_amount
                    if(Yii::$app->params['wx_appid'] == $data['appid']){ //4.验证 app_id
                        if($reware['status'] != 1){
                            $rereward_user = User::findOne(['id'=>$reware['rereward_id']]);
                            $user_balance = $rereward_user['balance'];//获取的用户余额
                            $end_balance = $user_balance + $reware['money'];//计算结算后的余额
                            if(!User::updateAll(['balance'=>$end_balance],['id'=>$reware['rereward_id']])){ //更新余额
                                $this->logs('用户余额修改失败: '.$end_balance.'--'.$reware['rereward_id'],2,'wx');
                            }

                            if(!Reward::updateAll(['status'=>1],['order_num'=>$reware['order_num']])){ //修改打赏表状态
                                $this->logs('Reward表修改状态失败: '.$reware['order_num'],2,'wx');
                            }
                            //查询打赏人信息
                            $reward_user = User::findOne(['id'=>$reware['reward_id']]);
                            $reware_name = $reward_user['nickname'] != '' ? $reward_user['nickname'] : func::replace_phone($reward_user['phone']);

                            //查询文章信息
                            $news = $this->getContent($reware['catid'],$reware['news_id']);

                            //被打赏人 金额流水记录增加
                            $Balancewater = new Balancewater();
                            $msg = $reware_name.'打赏了您的文章《'.$news->title.'》'.$reware['money'].'元';
                            if(!$Balancewater->add($reware['rereward_id'],$reware['reward_id'],2,3,$reware['order_num'],1,$reware['money'],$end_balance,$msg,json_encode($post))){ //金额流水记录增加
                                $this->logs('被打赏人user_balance_water表增加流水失败: '.json_encode($Balancewater->getFirstErrors()),2);
                            }

                            //打赏人 金额流水记录
                            $Balancewater = new Balancewater();
                            $msg = '您打赏了文章《'.$news->title.'》'.$reware['money'].'元';
                            if(!$Balancewater->add($reware['reward_id'],$reware['rereward_id'],1,2,$reware['order_num'],2,$reware['money'],$reward_user['balance'],$msg,json_encode($post))){ //金额流水记录增加
                                $this->logs('打赏人user_balance_water表减少流水失败: '.json_encode($Balancewater->getFirstErrors()),2);
                            }
                            //发送消息
                            $msg = new Msg();
                            $msg->take_uid = $reware['rereward_id'];
                            $msg->send_uid = 0;
                            $msg->message = $reware_name.'打赏了您的文章《'.$news->title.'》'.$reware['money'].'元';
                            $msg->type = 99;
                            $msg->url = '';
                            $msg->time = date('Y-m-d H:i:s');
                            $msg->isread = 0;
                            $msg->isNewRecord = true;
                            $msg->save();

                            $this->logs('wx_notify 验证通过',1,'wx');

                            //统计系统推送
                            try{
                                $news_data = News::getInfoSim($reware['news_id'],$reware['catid']);
                                if($news_data['thirdid'] !='' || $news_data['thirdid'] != 0){
                                    $user = func::IdToUser($news_data['thirdid']);
                                    $nickname = $user->nickname != '' ? $user->nickname :func::replace_phone($user->phone);
                                    $phone = $user->phone;
                                    $data = '{"User_id":'.$reware['rereward_id'].',"Article_id":'.$reware['news_id'].',"Article_type":'.$reware['catid'].',"Reward_channel":2,"Reward_money":'.$reware['money'].',"Reward_time":"'.date('Y-m-d H:i:s').'","Article_title":"'.$news_data['title'].'","Nickname":""'.$nickname.'","Phone":'.$phone.'}';
                                    $data = array('data' => $data,'key'=>'c3RhdGlzdGlj');
                                    $json = func::GoCurl('/api/reward/insert',  'POST',$data, $error_msg);
                                    $array = json_decode($json, true);
                                    if($array['Code'] != 10000){

                                    }
                                }
                            }catch (Exception $e){}
                            //统计系统推送

                            $this->_weixin_obj->replyNotify();
                        }else{
                            $this->logs('4.status状态已修改:'.json_encode($reware),2,'wx');exit();
                        }
                    }else{
                        $this->logs('4.验证 app_id错误:'.$this->_alipay_obj->appId.'<-->'.$data['app_id'],2,'wx');exit();
                    }
                }else{
                    $this->logs('2.验证 total_fee错误:'.$data['out_trade_no'].'--'.$reware['money'].'<-->'.$data['total_fee'],2,'wx');exit();
                }
            }else{
                $this->logs('1.验证 out_trade_no错误:'.$data['out_trade_no'],2,'wx');exit();
            }

        }
    }

    /*
     * 获取用户信息
     * @param $catid
     * @param $content_id
     * @return null|static
     * @throws \yii\web\NotFoundHttpException
     */
    public function getContent($catid, $content_id)
    {
        $news_table = '{{%'.News::getTable($catid).'}}';
        $news_model = new Mar($news_table);
        $data = $news_model->findOne(['id'=>$content_id]);
        return $data;
    }

    /*
     * 日志记录
     * @param $logs
     * @param $status 1:成功 2:失败
     */
    function logs($logs,$status,$type='alipay'){
        if($status == 1){
            $file = './logs/'.$type.'_success.txt';
        }else{
            $file = './logs/'.$type.'_error.txt';
        }
        file_put_contents($file,date('Y-m-d H:i:s').PHP_EOL.$logs.PHP_EOL,FILE_APPEND);//记录错误日志
    }


}
